//
//  PomodoroTimerView.swift
//  CatPomodoroTimer
//
//  Created by Xuri Li on 2024/7/30.
//

import SwiftUI

enum PTimerStatus: Int {
    case start
    case pause
    case stop
}

struct PomodoroTimerView: View {
    @EnvironmentObject var modelData: ModelData
    @EnvironmentObject var audioPlayer: AudioPlayer
    @State var quoteMsg: String
    @State private var timeRemaining: Double
    @State private var pTimerStatus: PTimerStatus = .stop
    @State private var timer: Timer? = nil
    @State private var playCatAnimation = false
    @State private var totalTime: Double = 0.0
    @State private var profile = ProfileManager().loadProfile()
    
    @State private var bgIndex: Int = UserDefaults.standard.value(forKey: "CAT_PT_BG_INDEX") as? Int ?? 1
    
    @State private var isNotchScreen: Bool = false
    
    @State private var focusTask: FocusTask? // 当前任务
    @State private var completedTasksToday: Int = 0 // 今日完成任务数
    @State private var endTimestamp: TimeInterval = 0
    
    init(quoteMsg: String) {
        _quoteMsg = State(initialValue: quoteMsg)
        _timeRemaining = State(initialValue: 0)
    }
    
    var body: some View {
        GeometryReader { geometry in
            NavigationView {
                ZStack(alignment: .top) {
                    Image("t_bg_\(bgIndex)")
                        .resizable()
                        .scaledToFill()
                        .frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
                        .edgesIgnoringSafeArea(.all)
                        .overlay(Color.black.opacity(0.1))
                    VStack {
                        Text("「 \(quoteMsg) 」")
                            .foregroundStyle(.white)
                            .font(.subheadline)
                            .padding(.top, isNotchScreen ? 120 : 60)
                        
                        ZStack {
                            Circle()
                                .stroke(Color.white.opacity(0.5), lineWidth: 4)
                                .frame(width: 300, height: 300)
                                .padding(10)
                            Circle()
                                .trim(from: 1 - CGFloat(timeRemaining / totalTime), to: 1)
                                .stroke(Color.white, lineWidth: 4)
                                .frame(width: 300, height: 300)
                                .padding(10)
                                .rotationEffect(.degrees(-90))
                                .animation(.linear(duration: 1), value: timeRemaining)
                            Text(timeString)
                                .font(.system(size: 40))
                                .foregroundStyle(.white)
                            if profile.isShowCat {
                                CatSleepAnimationView(isSleeping: $playCatAnimation)
                                    .frame(width: 60, height: 60)
                                    .padding(.top, 180)
                            }
                        }
                        .padding(.top, 40)

                        if profile.isShowCount {
                            HStack {
                                Text("今日专注次数")
                                    .foregroundStyle(.white)
                                    .font(.subheadline)
                                Image(systemName: "clock.badge.checkmark.fill") // stopwatch
                                    .foregroundColor(Color(hex: 0xC0FDFC))
                                    .font(.title3)
                                Image(systemName: "xmark")
                                    .foregroundColor(Color(hex: 0xC0FDFC))
                                    .font(.subheadline)
                                Text("\(completedTasksToday)")
                                    .foregroundStyle(Color(hex: 0xC0FDFC))
                                    .font(.title3)
                                
                            }
                            .padding()
                        }
                        
                        HStack {
                            NavigationLink {
                                WhiteNoise()
                            } label: {
                                VStack {
                                    ZStack {
                                        Circle()
                                            .stroke(.white)
                                            .frame(width: 40, height: 40)
                                            .overlay {
                                                Image(systemName: "music.note")
                                                    .foregroundStyle(.white)
                                                    .font(.title)
                                            }
                                            .padding(EdgeInsets())
                                        if let id = ModelData.shared.currentSelectedNoise?.id,
                                           id > 1 {
                                            // 不显示斜杠
                                        } else {
                                            Image(systemName: "line.diagonal")
                                                .foregroundStyle(.white)
                                                .font(.title)
                                                .frame(width: 40, height: 40)
                                                .rotationEffect(.degrees(90))
                                        }
                                    }
                                    .padding(EdgeInsets(top: 10, leading: 0, bottom: 2, trailing: 0))
                                    Text(ModelData.shared.currentSelectedNoise?.title ?? "无音乐")
                                        .foregroundStyle(.white)
                                        .font(.subheadline)
                                        .padding(EdgeInsets(top: 2, leading: 0, bottom: 2, trailing: 0))
                                }
                            }
                            Button(action: {
                                if self.pTimerStatus == .start {
                                    self.pauseTimer()
                                } else {
                                    self.startTimer()
                                }
                            }, label: {
                                if self.pTimerStatus == .start {
                                    VStack {
                                        Image(systemName: "pause.circle.fill")
                                            .font(.system(size: 60))
                                            .foregroundStyle(.white)
                                            .padding(.bottom, 2)
                                        Text("暂停")
                                            .foregroundStyle(.white)
                                            .font(.subheadline)
                                    }
                                } else {
                                    VStack {
                                        Image(systemName: "play.circle.fill")
                                            .font(.system(size: 60))
                                            .foregroundStyle(.white)
                                            .padding(.bottom, 2)
                                        Text(self.pTimerStatus == .pause ? "继续" : "开始")
                                            .foregroundStyle(.white)
                                            .font(.subheadline)
                                    }
                                }
                            })
                            .padding(EdgeInsets(top: 0, leading: 20, bottom: 0, trailing: 20))
                            VStack {
                                LongPressButtonView(pTimerStatus: pTimerStatus) {
                                    if self.pTimerStatus == .start || self.pTimerStatus == .pause {
                                        self.stopTimer()
                                    }
                                }
                                .padding(EdgeInsets(top: 10, leading: 0, bottom: 2, trailing: 0))
                                Text("停止")
                                    .foregroundStyle(.white)
                                    .font(.subheadline)
                            }
                        }
                        .onDisappear {
                            if self.pTimerStatus == .start {
                                self.pauseTimer()
                            }
                        }
                    }
                    .navigationTitle("") // Empty string if you don't want a title
                    .navigationBarTitleDisplayMode(.inline) // Makes the title smaller
                    .toolbar {
                        ToolbarItem(placement: .topBarLeading) {
                            Button(action: {
                                var index = bgIndex
                                index += 1
                                if index > 18 { index = 1 }
                                self.bgIndex = index
                                UserDefaults.standard.setValue(index, forKey: "CAT_PT_BG_INDEX")
                            }) {
                                Image(systemName: "photo.on.rectangle.angled")
                                    .foregroundStyle(.white)
                                    .font(.subheadline)
                            }
                        }
                        
                        ToolbarItem(placement: .topBarTrailing) {
                            NavigationLink {
                                ProfileEditor(profile: $profile) {
                                    self.totalTime = Double(profile.focusDuration.rawValue) * 60.0
                                    self.timeRemaining = self.totalTime
                                    self.stopTimer()
                                    
                                }
                            } label: {
                                Image(systemName: "slider.horizontal.3")
                                    .foregroundStyle(.white)
                                    .font(.subheadline)
                            }
                        }
                    }
                    .onAppear {
                        let safeAreaInsets = geometry.safeAreaInsets
                        self.isNotchScreen = safeAreaInsets.top > 20
                        // Fetch today's completed tasks
                        do {
                            self.completedTasksToday = try FocusTaskManager.fetchCompletedTasksForTodayCount()
                        } catch {
                            print("Error fetching completed tasks for today count \(error)")
                        }
                    }
                }
            }
            .onAppear {
                self.totalTime = Double(profile.focusDuration.rawValue) * 60.0
                self.timeRemaining = self.totalTime
            }
        }
    }
    
    private func startCatAudio() {
        guard profile.isShowCat else { return }
        withAnimation {
            self.playCatAnimation = true
        }
        audioPlayer.playSoundLoop(file: "cat", isDefaultPlayer: false)
    }
    
    private func stopCatAudio() {
        guard profile.isShowCat else { return }
        withAnimation {
            self.playCatAnimation = false
        }
        audioPlayer.stopSound(isDefaultPlayer: false)
    }
    
    private func startNoise() {
        if let noise = modelData.currentSelectedNoise,
           noise.id > 1 {
            audioPlayer.playSoundLoop(file: noise.fileName)
        }
    }
    
    private func stopNoise() {
        if let noise = modelData.currentSelectedNoise,
           noise.id > 1 {
            audioPlayer.stopSound()
        }
    }
    
    private func startTimer() {
        // Create a new task and insert it into the database
        let newTask = FocusTask(focusDurationLevel: profile.focusDuration)
        do {
            let task = try FocusTaskManager.insert(task: newTask)
            self.focusTask = task
        } catch {
            print("Error inserting task: \(error)")
        }
        
        let nowTimestamp = Date().timeIntervalSince1970
        self.endTimestamp = nowTimestamp + self.timeRemaining
//        print("nowTimestamp: \(nowTimestamp) \n endTimestamp: \(self.endTimestamp)")
        
        self.pTimerStatus = .start
        startCatAudio()
        startNoise()
        timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { tim in
            let tempTimestamp = Date().timeIntervalSince1970
            let timeInterval = self.endTimestamp - tempTimestamp
            self.timeRemaining = timeInterval
            if self.timeRemaining <= 0 {
                self.stopTimer(true)
            }
        }
        timer?.fire()
    }
    
    private func pauseTimer() {
        
        let nowTimestamp = Date().timeIntervalSince1970
        self.endTimestamp = nowTimestamp + self.timeRemaining
        
        self.pTimerStatus = .pause
        stopCatAudio()
        stopNoise()
        self.timer?.invalidate()
        self.timer = nil
    }
    
    
    /// Stop timer
    /// - Parameter isAuto: countdown ends and automatically stops
    private func stopTimer(_ isAuto: Bool = false) {
        if var currentTask = focusTask {
            currentTask.endDate = Date()
            currentTask.status = isAuto ? .complete : .incomplete
            
            do {
                try FocusTaskManager.update(task: currentTask)
                if currentTask.status == .complete {
                    self.completedTasksToday += 1
                }
            } catch {
                print("Error updateing task: \(error)")
            }
        }
        
        self.pTimerStatus = .stop
        stopCatAudio()
        stopNoise()
        if profile.vibrationFeedback {
            HapticFeedback.triggerImpactFeedback(style: .medium)
        }
        self.timer?.invalidate()
        self.timer = nil
        self.timeRemaining = totalTime
    }
    
    private var timeString: String {
        let minutes = Int(timeRemaining) / 60
        let seconds = Int(timeRemaining) % 60
        return String(format: "%02d:%02d", minutes, seconds)
    }
}

#Preview {
    PomodoroTimerView(quoteMsg: ModelData.shared.radomQuote)
}
